package com.czwj.annotation;


import java.lang.reflect.Method;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.czwj.entities.Log;
import com.czwj.entities.UserInfo;
import com.czwj.service.LogService;
import com.czwj.util.DateUtil;
import com.czwj.util.GsonUtil;    
    

@Aspect    
@Component    
public  class SystemLogAspect implements Ordered{    
	
    //注入Service用于把日志保存数据库    
    @Resource    
     private LogService logService;    
    //本地异常日志记录对象    
     private  static  final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);    
    
    //Service层切点    
    @Pointcut("@annotation(com.czwj.annotation.SystemServiceLog)")    
     public  void serviceAspect() {    
    }    
    
    //Controller层切点    
    @Pointcut("@annotation(com.czwj.annotation.SystemControllerLog)")    
     public  void controllerAspect() {    
    }    
    
    /**  
     * 前置通知 用于拦截Controller层记录用户的操作  
     *  
     * @param joinPoint 切点  
     */    
    @After("controllerAspect()")
     public  void doAfter(JoinPoint joinPoint) {    
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    
        HttpSession session = request.getSession();    
        //读取session中的用户    
        UserInfo user = (UserInfo) session.getAttribute("userInfo");    
        //请求的IP    
        String ip = request.getRemoteAddr();    
        String params = "";    
        if (joinPoint.getArgs() !=  null && joinPoint.getArgs().length > 0) {    
             for ( int i = 0; i < joinPoint.getArgs().length; i++) {    
            	 try {
					params += GsonUtil.objectToJsonStr(joinPoint.getArgs()[i]) + ";";
				} catch (Exception e1) {
					// TODO Auto-generated catch block
				}    
            }    
        }    
         try {    
            //*========控制台输出=========*//    
//            System.out.println("=====前置通知开始=====");    
//            System.out.println("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));    
//            System.out.println("方法描述:" + getControllerMethodDescription(joinPoint));  
//            if(user != null)
//            {
//            	System.out.println("请求人:" + user.getName());  
//            }
//            System.out.println("请求IP:" + ip);    
            //*========数据库日志=========*//    
            Log log = new Log(); 
            log.setDescription(getControllerMethodDescription(joinPoint));    
            log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));    
            log.setType("0");    
            log.setRequestip(ip);    
            log.setExceptioncode( null);    
            log.setExceptiondetail( null);    
//            log.setParams( params);   
            if(user != null)
            {
            	log.setCompanyid(user.getCompanyid());
            	log.setUsername(user.getName());
            }
            log.setCreatedate(DateUtil.convert(new Date(), "yyyy-MM-dd HH:mm:ss"));    
            //保存数据库    
            logService.insert(log);    
//            System.out.println("=====前置通知结束=====");    
        }  catch (Exception e) {    
            //记录本地异常日志    
            logger.error("==前置通知异常==");    
            logger.error("异常信息:{}", e);    
        }    
    }    
    
    /**  
     * 异常通知 用于拦截service层记录异常日志  
     *  
     * @param joinPoint  
     * @param e  
     */    
    @AfterThrowing(pointcut = "serviceAspect()", throwing = "e") 
     public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {    
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    
        HttpSession session = request.getSession();    
        //读取session中的用户    
        UserInfo user = (UserInfo) session.getAttribute("userInfo");    
        //获取请求ip    
        String ip = request.getRemoteAddr();    
        //获取用户请求方法的参数并序列化为JSON格式字符串    
        String params = "";    
        if (joinPoint.getArgs() !=  null && joinPoint.getArgs().length > 0) {    
             for ( int i = 0; i < joinPoint.getArgs().length; i++) {    
            	 try {
					params += GsonUtil.objectToJsonStr(joinPoint.getArgs()[i]) + ";";
				} catch (Exception e1) {
					// TODO Auto-generated catch block
				}    
            }    
        }    
         try {    
              /*========控制台输出=========*/    
            System.out.println("=====异常通知开始=====");    
            System.out.println("异常代码:" + e.getClass().getName());    
            System.out.println("异常信息:" + e.getMessage());    
            System.out.println("异常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));    
            System.out.println("方法描述:" + getServiceMthodDescription(joinPoint));    
            if(user != null)
            {
            	System.out.println("请求人:" + user.getName());  
            } 
            System.out.println("请求IP:" + ip);    
            System.out.println("请求参数:" + params);    
               /*==========数据库日志=========*/    
            Log log = new Log(); 
            log.setDescription(getServiceMthodDescription(joinPoint));    
            log.setExceptioncode(e.getClass().getName());    
            log.setType("1");    
            log.setExceptiondetail(e.getMessage());    
            log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));    
//            log.setParams(params);    
            if(user != null)
            {
            	log.setCompanyid(user.getCompanyid());
            	log.setUsername(user.getName());    
            }  
            log.setCreatedate(DateUtil.convert(new Date(), "yyyy-MM-dd HH:mm:ss"));    
            log.setRequestip(ip);    
            //保存数据库    
            logService.insert(log);  
//            sendEmail(log.getDescription(),log.getExceptionCode(),log.getExceptionDetail(),log.getMethod(),log.getParams(),log.getRequestIp());
            System.out.println("=====异常通知结束=====");    
        }  catch (Exception ex) {    
            //记录本地异常日志    
            logger.error("==异常通知异常==");    
            logger.error("异常信息:{}", ex.getMessage());    
        }    
         /*==========记录本地异常日志==========*/    
        logger.error("异常方法:{}异常代码:{}异常信息:{}参数:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getMessage(), params);
    }    
    
    
    /**  
     * 获取注解中对方法的描述信息 用于service层注解  
     *  
     * @param joinPoint 切点  
     * @return 方法描述  
     * @throws Exception  
     */    
     public  static String getServiceMthodDescription(JoinPoint joinPoint)    
             throws Exception {    
        String targetName = joinPoint.getTarget().getClass().getName();    
        String methodName = joinPoint.getSignature().getName();    
        Object[] arguments = joinPoint.getArgs();    
        Class targetClass = Class.forName(targetName);    
        Method[] methods = targetClass.getMethods();    
        String description = "";    
         for (Method method : methods) {    
             if (method.getName().equals(methodName)) {    
                Class[] clazzs = method.getParameterTypes();    
                 if (clazzs.length == arguments.length) {    
                    description = method.getAnnotation(SystemServiceLog. class).description();    
                     break;    
                }    
            }    
        }    
         return description;    
    }    
    
    /**  
     * 获取注解中对方法的描述信息 用于Controller层注解  
     *  
     * @param joinPoint 切点  
     * @return 方法描述  
     * @throws Exception  
     */    
     public  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {    
        String targetName = joinPoint.getTarget().getClass().getName();    
        String methodName = joinPoint.getSignature().getName();    
        Object[] arguments = joinPoint.getArgs();    
        Class targetClass = Class.forName(targetName);    
        Method[] methods = targetClass.getMethods();    
        String description = "";    
         for (Method method : methods) {    
             if (method.getName().equals(methodName)) {    
                Class[] clazzs = method.getParameterTypes();    
                 if (clazzs.length == arguments.length) {    
                    description = method.getAnnotation(SystemControllerLog. class).description();    
                     break;    
                }    
            }    
        }    
         return description;    
    }    

     
//     public void sendEmail(String Description,String ExceptionCode,String ExceptionDetail,String Method,String Params,String IpAddr) {
//    	 
//    	 String from_email = PropertyUtil.getProperty("from_email");
//    	 String email_password = PropertyUtil.getProperty("email_password");
//    	 String to_email = PropertyUtil.getProperty("to_email");
//    	 String[] to_emails = null;
//    	 if(TextUtil.isNotEmpty(to_email))
//    	 {
//    		 to_emails = to_email.split(",");
//    	 }
//    	 Properties props = new Properties();	
//         props.setProperty("mail.transport.protocol", "smtp");
//         props.setProperty("mail.smtp.host", "smtp.nj-int.com");
//         props.setProperty("mail.smtp.auth", "true"); 
//         props.setProperty("mail.smtp.port", "465");
//         props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
//         props.setProperty("mail.smtp.socketFactory.fallback", "false");
//         props.setProperty("mail.smtp.socketFactory.port", "465");
//         Session msession= Session.getInstance(props);
//         //msession.setDebug(true);
//         MimeMessage message = new MimeMessage(msession);
//         
//         try {
//        	 message.setFrom(new InternetAddress(from_email, "", "UTF-8"));
//             message.setSubject("系统异常", "UTF-8");
//             String content = "";
//             content += "功能描述：" + Description +"<br>";
//             content += "错误方法：" + Method  +"<br>";
//             content += "参数：" + Params + "<br>";
//             content += "请求IP：" + Params + "<br>";
//             content += "异常代码：" + ExceptionCode + "<br>";
//             content += "异常信息：" + ExceptionDetail;
//             message.setContent(content, "text/html;charset=UTF-8");
//             message.setSentDate(new Date());
//             message.saveChanges();
//             //OutputStream out = new FileOutputStream("d://MyEmail.eml");
//             //message.writeTo(out);
//             //out.flush();
//             //out.close();
//             Transport transport = msession.getTransport();
//			 transport.connect(from_email, email_password);
//			 if(transport.isConnected())
//			 {
//				 if(to_emails!=null)
//				 {
//					 for (String string : to_emails) {
//						 message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(string, "", "UTF-8"));
//						 transport.sendMessage(message, message.getAllRecipients());
//					 }	     
//				 }    
//			 }
//	         transport.close();
//		} catch (MessagingException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (UnsupportedEncodingException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//         
//	}

	public int getOrder() {
		// TODO Auto-generated method stub
		return 0;
	}
}    